using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Book.Blog.Core.DTOs;
using Book.Blog.Core.Entities;
using Book.Blog.Core.Interfaces;
using System.Linq;

namespace Book.Blog.API.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class TagsController : ControllerBase
    {
        private readonly IRepository<Tag> _tagRepository;
        private readonly IUnitOfWork _unitOfWork;

        public TagsController(
            IRepository<Tag> tagRepository,
            IUnitOfWork unitOfWork)
        {
            _tagRepository = tagRepository;
            _unitOfWork = unitOfWork;
        }

        /// <summary>
        /// 获取所有标签列表
        /// </summary>
        /// <returns>标签列表</returns>
        [HttpGet]
        public async Task<ActionResult<IEnumerable<TagDTO>>> GetTags()
        {
            var tags = await _unitOfWork.Tags.GetAllAsync();
            return Ok(tags.Select(t => new TagDTO
            {
                Id = t.Id,
                Name = t.Name,
                Description = t.Description,
                Slug = t.Slug,
                PostCount = t.PostCount
            }));
        }

        /// <summary>
        /// 根据ID获取标签详情
        /// </summary>
        /// <param name="id">标签ID</param>
        /// <returns>标签详情</returns>
        [HttpGet("{id}")]
        public async Task<ActionResult<TagDTO>> GetTag(Guid id)
        {
            var tag = await _unitOfWork.Tags.GetByIdAsync(id);
            if (tag == null)
            {
                return NotFound();
            }

            return new TagDTO
            {
                Id = tag.Id,
                Name = tag.Name,
                Description = tag.Description,
                Slug = tag.Slug,
                PostCount = tag.PostCount
            };
        }

        /// <summary>
        /// 根据slug获取标签详情
        /// </summary>
        /// <param name="slug">标签slug</param>
        /// <returns>标签详情</returns>
        [HttpGet("slug/{slug}")]
        public async Task<ActionResult<TagDTO>> GetTagBySlug(string slug)
        {
            var tags = await _unitOfWork.Tags.GetAllAsync();
            var tag = await tags.AsQueryable().FirstOrDefaultAsync(t => t.Slug == slug);
            if (tag == null)
            {
                return NotFound();
            }

            return new TagDTO
            {
                Id = tag.Id,
                Name = tag.Name,
                Description = tag.Description,
                Slug = tag.Slug,
                PostCount = tag.PostCount
            };
        }

        /// <summary>
        /// 创建新标签（需管理员权限）
        /// </summary>
        /// <param name="model">标签信息</param>
        /// <returns>新建标签详情</returns>
        /// <remarks>
        /// 示例请求:
        /// {
        ///   "name": "C#",
        ///   "description": "C#相关内容",
        ///   "slug": "csharp"
        /// }
        /// </remarks>
        [HttpPost]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<TagDTO>> CreateTag(CreateTagDTO model)
        {
            var tags = await _unitOfWork.Tags.GetAllAsync();
            var existingTag = await tags.AsQueryable().FirstOrDefaultAsync(t => t.Slug == model.Slug);
            if (existingTag != null)
            {
                return BadRequest("标签已存在");
            }

            var tag = new Tag
            {
                Name = model.Name,
                Description = model.Description,
                Slug = model.Slug
            };

            await _unitOfWork.Tags.AddAsync(tag);
            await _unitOfWork.SaveChangesAsync();

            return CreatedAtAction(nameof(GetTag), new { id = tag.Id }, new TagDTO
            {
                Id = tag.Id,
                Name = tag.Name,
                Description = tag.Description,
                Slug = tag.Slug,
                PostCount = tag.PostCount
            });
        }

        /// <summary>
        /// 更新标签（需管理员权限）
        /// </summary>
        /// <param name="id">标签ID</param>
        /// <param name="model">标签信息</param>
        /// <returns>无内容</returns>
        /// <remarks>
        /// 示例请求:
        /// {
        ///   "name": "C#",
        ///   "description": "C#相关内容",
        ///   "slug": "csharp"
        /// }
        /// </remarks>
        [HttpPut("{id}")]
        [Authorize(Roles = "Admin")]
        public async Task<IActionResult> UpdateTag(Guid id, UpdateTagDTO model)
        {
            var tag = await _unitOfWork.Tags.GetByIdAsync(id);
            if (tag == null)
            {
                return NotFound();
            }

            // 检查新的 slug 是否已存在
            if (model.Slug != tag.Slug)
            {
                var tags = await _unitOfWork.Tags.GetAllAsync();
                var existingTag = await tags.AsQueryable().FirstOrDefaultAsync(t => t.Slug == model.Slug);
                if (existingTag != null)
                {
                    return BadRequest("标签已存在");
                }
            }

            tag.Name = model.Name;
            tag.Description = model.Description;
            tag.Slug = model.Slug;
            tag.UpdatedAt = DateTime.UtcNow;

            await _unitOfWork.SaveChangesAsync();

            return NoContent();
        }

        /// <summary>
        /// 删除标签（需管理员权限）
        /// </summary>
        /// <param name="id">标签ID</param>
        /// <returns>无内容</returns>
        [HttpDelete("{id}")]
        [Authorize(Roles = "Admin")]
        public async Task<IActionResult> DeleteTag(Guid id)
        {
            var tag = await _unitOfWork.Tags.GetByIdAsync(id);
            if (tag == null)
            {
                return NotFound();
            }

            // 先移除所有关联的文章
            foreach (var post in tag.Posts.ToList())
            {
                tag.Posts.Remove(post);
                post.Tags.Remove(tag);
            }

            await _unitOfWork.Tags.DeleteAsync(tag);
            await _unitOfWork.SaveChangesAsync();

            return NoContent();
        }
    }

    public class CreateTagDTO
    {
        public required string Name { get; set; }
        public string? Description { get; set; }
        public required string Slug { get; set; }
    }

    public class UpdateTagDTO
    {
        public required string Name { get; set; }
        public string? Description { get; set; }
        public required string Slug { get; set; }
    }
} 